package mygame.Backbone;

import mygame.Model.Planet;

import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.math.Matrix3f;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.CameraNode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.control.CameraControl.ControlDirection;

public class PlanetCam implements ActionListener,ICam{

	private Geometry planet;
	private Node planetCenter;
	private InputManager ipm;
	private CameraNode cam;
	private float dirZ;
	private float dirY;
	private float zoom;
	private float mindist;
	private float maxdist;
	private static final float mov = 1f;
	
	public PlanetCam(Camera cam, InputManager ipm,Node root) {
		this.cam = new CameraNode("camWrapper",cam);
		planetCenter = new Node("pcenter");
		root.attachChild(planetCenter);
		this.ipm = ipm;	
		this.dirZ = 0;
		this.dirY=0;
		this.zoom = 0;
		this.mindist = 0;
		this.maxdist = 0;
	}

	public void addPlanet(Planet planet){
		this.planet = planet.getGeom();
		this.mindist = planet.getSize()+1;
		this.maxdist = planet.getSize()*6;
	}
	
	@Override
	public void onAction(String name, boolean isPressed, float tpf) {
		if(name.equals(GlobalVars.ACTION_FORWARD)){
			this.dirZ = isPressed?-mov:0;
		}else if (name.equals(GlobalVars.ACTION_BACKWARD)){
			this.dirZ = isPressed?mov:0;
		}else if(name.equals(GlobalVars.ACTION_LEFT)){
			this.dirY = isPressed?mov:0;
		}else if (name.equals(GlobalVars.ACTION_RIGHT)){
			this.dirY = isPressed?-mov:0;
		}else if(name.equals(GlobalVars.ACTION_ZOOM_IN)){
			this.zoom = isPressed?-mov:0;
		}else if (name.equals(GlobalVars.ACTION_ZOOM_OUT)){
			this.zoom = isPressed?mov:0;
		}
		
		
	}
	
	@Override
	public void update(float tpf) {
		//planet.rotate(0, (FastMath.PI/180)*dirY, (FastMath.PI/180)*dirZ);
		planetCenter.rotate(0, dirY*tpf*2, dirZ*tpf*2);
		float temp = zoom*tpf*3;
		if(cam.getLocalTranslation().x+temp>=mindist && cam.getLocalTranslation().x+temp<=maxdist)
			cam.move(temp, 0, 0);
		}

	protected void rotateCamera(float value, float tpf, Vector3f axis,Camera cam){
		float rotationSpeed = 1000;
		 
		Matrix3f mat = new Matrix3f();
		mat.fromAngleNormalAxis(rotationSpeed * value * tpf, axis);
		 
		Vector3f upDir = cam.getUp();
		Vector3f leftDir = cam.getLeft();
		Vector3f dir = cam.getDirection();
		 
		mat.mult(upDir, upDir);
		mat.mult(leftDir, leftDir);
		mat.mult(dir, dir);
		 
		Quaternion q = new Quaternion();
		q.fromAxes(leftDir, upDir, dir);
		q.normalizeLocal();
		 
		cam.setAxes(q);
		 
		dir = cam.getDirection();
		dir = dir.mult(20.0f);
		Vector3f invDir = new Vector3f(-dir.x, -dir.y, -dir.z);
		Vector3f position = invDir.add(Vector3f.ZERO);
		cam.setLocation(position);
		}
	
	@Override
	public void registerWithInput() {
		ipm.addMapping(GlobalVars.ACTION_FORWARD, new KeyTrigger(KeyInput.KEY_UP));
		ipm.addMapping(GlobalVars.ACTION_BACKWARD, new KeyTrigger(KeyInput.KEY_DOWN));
		ipm.addMapping(GlobalVars.ACTION_LEFT, new KeyTrigger(KeyInput.KEY_LEFT));
		ipm.addMapping(GlobalVars.ACTION_RIGHT, new KeyTrigger(KeyInput.KEY_RIGHT));
		ipm.addMapping(GlobalVars.ACTION_ZOOM_IN, new KeyTrigger(KeyInput.KEY_PGUP));
		ipm.addMapping(GlobalVars.ACTION_ZOOM_OUT, new KeyTrigger(KeyInput.KEY_PGDN));
		
		String[] mapping = {
				GlobalVars.ACTION_FORWARD,
				GlobalVars.ACTION_BACKWARD,
				GlobalVars.ACTION_LEFT,
				GlobalVars.ACTION_RIGHT,
				GlobalVars.ACTION_ZOOM_IN,
				GlobalVars.ACTION_ZOOM_OUT
		};
		ipm.addListener(this, mapping);
	}

	@Override
	public void init() {
		ipm.setCursorVisible(true);
		planet.setLocalTranslation(Vector3f.ZERO);
		//planetCenter.attachChild(planet);
		cam.setControlDir(ControlDirection.SpatialToCamera);
		planetCenter.attachChild(cam);
		cam.setLocalTranslation(new Vector3f(mindist+(maxdist-mindist)/2,0,0));
		
		cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
	}

	@Override
	public Camera getCamera() {
		return this.cam.getCamera();
	}
	
	
	
	
	
}
